﻿using System;
using System.Linq;
using System.Windows.Forms;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.Client;
using Outlook.WorkItems.Extension.Controls;
using Microsoft.Office.Interop.Outlook;
using System.IO;
using System.Diagnostics;
using Outlook.WorkItems.Extension.Manager;
using Outlook.WorkItems.Extension.Managers;
using Exception = System.Exception;
using Outlook.WorkItems.Extension.Addin.Actions;

namespace Outlook.WorkItems.Extension.Addin.Forms
{
    public partial class CreateWorkItemWizard : Form
    {
        private string _projectName;
        private string _serverUri;
        private string _serverName;
        private WorkItemStore _wiStore;
        private WorkItem _selectedWorkItem;
        private readonly OutlookItem _outlookItem;
        private readonly Attachments _attachments;

        public CreateWorkItemWizard()
        {
            InitializeComponent();
        }

        public CreateWorkItemWizard(OutlookItem item)
            : this()
        {
            _outlookItem = item;
            _attachments = _outlookItem.Attachments;
            try
            {
                var project = FavoritesTeamProjectManager.GetDefaultTeamProject();
                if (project != null)
                {
                    _serverUri = project.TeamServerUri;
                    _projectName = project.TeamProjectName;

                    var server = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(_serverUri));
                    _serverName = server.Name;
                    _wiStore = server.GetService<WorkItemStore>();
                    textBox1.Text = string.Format("{0} - {1}", _serverName, _projectName);
                    radioNewWorkItem.Enabled = true;
                    radioExistingWorkItem.Enabled = true;
                    chkAddMailToWIAttach.Enabled = true;
                    listView1.Enabled = true;
                    cbWorkItemTypes.Enabled = radioNewWorkItem.Checked;
                    btnDefineMapping.Enabled = radioNewWorkItem.Checked;

                    InitWorkItemTypes();
                }
            }
            catch (Exception) { }

        }

        private void chkAddMailToWIAttach_CheckedChanged(object sender, EventArgs e)
        {
            cbFormat.Enabled = chkAddMailToWIAttach.Checked;
        }

        private void btnSelectTP_Click(object sender, EventArgs e)
        {
            try
            {
                using (var frm = new SelectTeamProjectForm())
                {
                    if (frm.ShowDialog() == DialogResult.OK)
                    {
                        Cursor = Cursors.WaitCursor;
                        _projectName = frm.ProjectName;

                        _serverUri = frm.ServerUri;
                        var server = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(_serverUri));
                        _serverName = server.Name;
                        _wiStore = server.GetService<WorkItemStore>();
                        textBox1.Text = string.Format("{0} - {1}", _serverName, _projectName);
                        radioNewWorkItem.Enabled = true;
                        radioExistingWorkItem.Enabled = true;
                        chkAddMailToWIAttach.Enabled = true;
                        listView1.Enabled = true;
                        cbWorkItemTypes.Enabled = radioNewWorkItem.Checked;
                        btnDefineMapping.Enabled = radioNewWorkItem.Checked;

                        InitWorkItemTypes();
                    }
                }
            }
            catch (Exception ex)
            {
                using (var frm = new ErrorForm(ex))
                {
                    frm.ShowDialog(this);
                }
            }
            finally
            {
                Cursor = Cursors.Default;
            }
        }

        private void radioExistingWorkItem_CheckedChanged(object sender, EventArgs e)
        {
            radioNewWorkItem.Checked = !radioExistingWorkItem.Checked;
            cbWorkItemTypes.Enabled = radioNewWorkItem.Checked;
            btnDefineMapping.Enabled = radioNewWorkItem.Checked;
            btnSelectWorkItem.Enabled = !radioNewWorkItem.Checked;
        }

        private void radioNewWorkItem_CheckedChanged(object sender, EventArgs e)
        {
            radioExistingWorkItem.Checked = !radioNewWorkItem.Checked;
            cbWorkItemTypes.Enabled = radioNewWorkItem.Checked;
            btnDefineMapping.Enabled = radioNewWorkItem.Checked;
            btnSelectWorkItem.Enabled = !radioNewWorkItem.Checked;
        }

        private void CreateWorkItemWizard_Load(object sender, EventArgs e)
        {
            foreach (Microsoft.Office.Interop.Outlook.Attachment item in _attachments)
            {
                if (item.Type != OlAttachmentType.olByValue)
                    continue;

                var lvi = new ListViewItem(item.DisplayName);
                var extension = item.DisplayName.Substring(item.DisplayName.LastIndexOf("."), item.DisplayName.Length - item.DisplayName.LastIndexOf("."));
                lvi.ImageIndex = IconsCache.GetIconIndex(fileExtensionImageList, extension);
                lvi.Tag = item;
                var lvsi = new ListViewItem.ListViewSubItem(lvi, ((double)item.Size / 1024f).ToString("0 KB"));
                lvi.SubItems.Add(lvsi);
                listView1.Items.Add(lvi);
            }

            cbFormat.Items.Clear();
            cbFormat.Items.Add(new FormatMail(OlSaveAsType.olTXT, "Text only (*.txt)"));
            cbFormat.Items.Add(new FormatMail(OlSaveAsType.olMSG, "Outlook Message Format (*.msg)"));
            cbFormat.Items.Add(new FormatMail(OlSaveAsType.olMSGUnicode, "Outlook Message Format - Unicode (*.msg)"));
            cbFormat.Items.Add(new FormatMail(OlSaveAsType.olHTML, "HTML (*.htm;*.html)"));
            cbFormat.Items.Add(new FormatMail(OlSaveAsType.olMHTML, "MHT Files (*.mht)"));
        }

        private void InitWorkItemTypes()
        {
            cbWorkItemTypes.Items.Clear();
            foreach (var witi in
                from WorkItemType item in _wiStore.Projects[_projectName].WorkItemTypes
                select new WorkItemTypeItem(item))
            {
                cbWorkItemTypes.Items.Add(witi);
            }
        }

        private void listView1_DoubleClick(object sender, EventArgs e)
        {
            if (listView1.SelectedItems == null || listView1.SelectedItems.Count != 1)
                return;

            var att = listView1.SelectedItems[0].Tag as Microsoft.Office.Interop.Outlook.Attachment;
            if (att == null)
                return;

            var path = Path.Combine(Path.GetTempPath(), att.FileName);

            att.SaveAsFile(path);

            Process.Start(path);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            using (
                var workItemMappingForm = new WorkItemMappingForm(Globals.ThisAddIn.Application,
                                                                  ((WorkItemTypeItem)cbWorkItemTypes.SelectedItem).
                                                                      WorkItemType, _outlookItem))
            {
                if (workItemMappingForm.ShowDialog() == DialogResult.OK)
                {
                    _selectedWorkItem = workItemMappingForm.WorkItem;
                }
            }
        }

        private void btnSelectWorkItem_Click(object sender, EventArgs e)
        {
            using (var frm = new SelectWorkItemForm(_wiStore, _projectName))
            {
                if (frm.ShowDialog() != DialogResult.OK)
                    return;

                _selectedWorkItem = frm.SelectedWorkItem;
                lblSelectedWorkItem.Text = string.Format("{0} - {1}", _selectedWorkItem.Id, _selectedWorkItem.Title);
            }
        }

        private void btnNext_Click(object sender, EventArgs e)
        {

            if (_selectedWorkItem == null)
                return;


            if (chkAddMailToWIAttach.Checked)
            {
                var fileName = _outlookItem.Subject;
                var regex = new System.Text.RegularExpressions.Regex("[^a-zA-Z0-9]");
                fileName = regex.Replace(fileName, "");

                var format = ((FormatMail)cbFormat.SelectedItem).Format;
                switch (format)
                {
                    case OlSaveAsType.olHTML:
                        fileName += ".htm";
                        break;
                    case OlSaveAsType.olMHTML:
                        fileName += ".mht";
                        break;
                    case OlSaveAsType.olMSG:
                    case OlSaveAsType.olMSGUnicode:
                        fileName += ".msg";
                        break;
                    case OlSaveAsType.olTXT:
                        fileName += ".txt";
                        break;
                    default:
                        break;
                }

                var path = Path.GetTempPath() + "\\" + fileName;
                _outlookItem.SaveAs(path, format);
                _selectedWorkItem.Attachments.Add(new Microsoft.TeamFoundation.WorkItemTracking.Client.Attachment(path, null));
            }

            foreach (ListViewItem item in listView1.CheckedItems)
            {
                var att = item.Tag as Microsoft.Office.Interop.Outlook.Attachment;

                var appDataFolder = Path.GetTempPath();
                if (att == null)
                    continue;

                var path = appDataFolder + "\\" + att.FileName;
                att.SaveAsFile(path);
                _selectedWorkItem.Attachments.Add(new Microsoft.TeamFoundation.WorkItemTracking.Client.Attachment(path, null));
            }

            _selectedWorkItem.Save();


            var relatedWorkItemsId = _outlookItem.ItemProperties["RelatedWIIds"];

            // Add Work Item Identifier to Item Properties of message
            if (relatedWorkItemsId == null)
            {
                _outlookItem.ItemProperties.Add("RelatedWIIds", OlUserPropertyType.olText, false);
                relatedWorkItemsId = _outlookItem.ItemProperties["RelatedWIIds"];
                relatedWorkItemsId.Value = "";
            }

            //var wiIds = relatedWorkItemsId.Value.ToString();
            //wiIds += _selectedWorkItem.Id;
            relatedWorkItemsId.Value = _selectedWorkItem.Id;

            var teamServer = _outlookItem.ItemProperties["TeamServer"];

            if (teamServer == null)
            {
                _outlookItem.ItemProperties.Add("TeamServer", OlUserPropertyType.olText, false);
                teamServer = _outlookItem.ItemProperties["TeamServer"];
            }
            teamServer.Value = _serverUri;

            _outlookItem.Save();
        }
    }
}
